/**
 * gcog - generate code with inlined Groovy code.
 * http://code.google.com/p/gcog/
 * 
 * Copyright 2008, Tobias Hientzsch.
 * 
 * MIT license http://www.opensource.org/licenses/mit-license.php
 * 
 * Original idea and code from Cog code generation tool.
 * http://nedbatchelder.com/code/cog
 *
 * Copyright 2004-2008, Ned Batchelder.
 * 
 */
 
import static WhiteUtils.*

public class GCogGenerator{

	def markers
	def lines
	
	def GCogGenerator() {
		markers = []
		lines = []
	}
	def parseMarker(l) {
	    markers << l
	}
	    
	def parseLine(l) {
	    lines << l
	}
	
    def getCode() {
        """ Extract the executable Groovy code from the generator.
        """
        // If the markers and lines all have the same prefix
        // (end-of-line comment chars, for example),
        // then remove it from all the lines.
        def prefIn = commonPrefix(markers + lines)
        if(prefIn) {
        	markers = markers.collect{ it.replaceFirst(prefIn, '') }
        	lines = lines.collect{ it.replaceFirst(prefIn, '') }

        }

        return reindentBlock(lines, '')
    }

    public String outString
    
    def evaluate(cog, globals, fname='gcog generator') {
        // figure out the right whitespace prefix for the output
        def prefOut = whitePrefix(markers)
        def intext = getCode()
        if (!intext) {
            return ''
        }
        outString = ''
        Binding binding = new Binding();
        binding.setVariable("cog", this)
        binding.setVariable("msg", msg)
        binding.setVariable("out", out)
        binding.setVariable("outl", outl)
        def shell = new GroovyShell(binding)
        try {
         shell.evaluate(intext)
        } catch(Exception e) {
        	println "error in script:<<<$intext>>>"
        	throw e;
        }

        return reindentBlock(outString, prefOut)
    }
    
    def msg = { s ->
		println s
    }
    
    def out = { s ->
		this.outString += s
    }
    
    def outl = { s ->
		this.outString += s + '\n'
    }
}
